package nba2kmodtool.filedesc;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import nba2kmodtool.filedesc.util3d.DX3Dmath;
import nba2kmodtool.util.BufferUtil;
import nba2kmodtool.util.ByteFileReader;

class N2kIgModelImporter {
	private static final boolean IS_DEBUG = BaseIffFile.IS_DEBUG;

	protected BaseIffFile iff;
	protected File file;

	protected N2kIgModelImporter(BaseIffFile iff) {
		this.iff = iff;
		this.file = iff.file;
	}

	private void importIg3DModelVertexData(ByteFileReader in, ByteFileReader out, int perSize, N2k3DModelPart model)
			throws IOException {
		int vertexNum = in.read4BytesAsInt();
		System.out.printf("Import Ig: %d-%d\n", model.vertexNum, vertexNum);
		if (vertexNum > model.vertexNum) {
			throw new IOException(String.format(
					"Import Model is Not Match to Resource Model:\nResource: %d\n, Import: %d", model.vertexNum,
					vertexNum));
		}
		ByteBuffer buffer = ByteBuffer.allocate(perSize * vertexNum);
		in.read(buffer.array());
		buffer.rewind();
		FloatBuffer vertexs = FloatBuffer.allocate(vertexNum * 3);
		FloatBuffer uvns = FloatBuffer.allocate(vertexNum * 2);
		for (int j = 0; j < vertexNum; j++) {
			vertexs.put(BufferUtil.readBytesAsFloat(buffer, 4));
			vertexs.put(BufferUtil.readBytesAsFloat(buffer, 4));
			vertexs.put(BufferUtil.readBytesAsFloat(buffer, 4));
			uvns.put(BufferUtil.readBytesAsFloat(buffer, 4));
			uvns.put(BufferUtil.readBytesAsFloat(buffer, 4));
		}
		vertexs.rewind();
		uvns.rewind();
		int perVertexSize = model.perVertexSize;
		int perUVNSize = model.perUVNSize;
		out.seek(model.vertexDataStart);
		if (model.dataChunkCount == 1) {
			for (int i = 0; i < vertexNum; i++) {
				out.writeFloatBigEndin(vertexs.get());
				out.writeFloatBigEndin(vertexs.get());
				out.writeFloatBigEndin(vertexs.get());
				if (!model.isUVvalid) {
					out.skipBytes(perVertexSize - 12);
					continue;
				}
				if ((perVertexSize - 12) == 0x28) {
					out.skipBytes(0x18);
					float tu = uvns.get();
					float tv = 1.0F - uvns.get();
					short[] uv = DX3Dmath.D3DXFloat32To16Array(new float[] { tu, tv });
					out.writeShortBigEndin(uv[0]);
					out.writeShortBigEndin(uv[1]);
					out.skipBytes(0x0C);
					continue;
				} else if ((perVertexSize - 12) == 0x24) {
					out.skipBytes(0x18);
					float tu = uvns.get();
					float tv = 1.0F - uvns.get();
					short u = (short) (tu * 32767.0F);
					short v = (short) (tv * 32767.0F);
					out.writeShortBigEndin(u);
					out.writeShortBigEndin(v);
					out.skipBytes(0x08);
					continue;
				} else {
					out.skipBytes(perVertexSize - 12);
				}
			}
		}
		//model type2
		else {
			if (perVertexSize < 12) {
				for (int i = 0; i < vertexNum; i++) {
					float tx = vertexs.get();
					float ty = vertexs.get();
					float tz = vertexs.get();
					short x = (short) (tx * 467.67F);
					short y = (short) (ty * 467.67F);
					short z = (short) (tz * 467.67F);
					out.writeShortBigEndin(x);
					out.writeShortBigEndin(y);
					out.writeShortBigEndin(z);
					out.skipBytes(0x02);
				}
			} else {
				for (int i = 0; i < vertexNum; i++) {
					out.writeFloatBigEndin(vertexs.get());
					out.writeFloatBigEndin(vertexs.get());
					out.writeFloatBigEndin(vertexs.get());
					out.skipBytes(perVertexSize - 12);
				}
			}
			if (IS_DEBUG)
				System.out.printf("CURvertPOS: %X--%d-%d\n", out.getFilePointer(), vertexNum, perVertexSize);
			for (int i = 0; i < (model.vertexNum - vertexNum); i++) {
				for (int j = 0; j < perVertexSize; j++) {
					out.write(0x00);
				}
			}
			if (!model.isUVvalid) {
				return;
			}
			//import uvn position datas
			out.seek(model.uvnDataStart);
			if (IS_DEBUG)
				System.out.printf("CURuvSTARTPOS: %X\n", out.getFilePointer());
			if (perUVNSize == 0x28) {
				for (int i = 0; i < vertexNum; i++) {
					out.skipBytes(0x18);
					out.writeFloatBigEndin(uvns.get());
					out.writeFloatBigEndin(1.0F - uvns.get());
					out.skipBytes(0x08);
				}
			} else if (perUVNSize == 0x24) {
				for (int i = 0; i < vertexNum; i++) {
					out.skipBytes(0x18);
					float tu = uvns.get();
					float tv = 1.0F - uvns.get();
					short u = (short) (tu * 32767.0F);
					short v = (short) (tv * 32767.0F);
					out.writeShortBigEndin(u);
					out.writeShortBigEndin(v);
					out.skipBytes(0x08);
				}
			} else if (perUVNSize == 0x18) {
				for (int i = 0; i < vertexNum; i++) {
					float tu = uvns.get();
					float tv = 1.0F - uvns.get();
					short u = (short) (tu * 32767.0F);
					short v = (short) (tv * 32767.0F);
					out.writeShortBigEndin(u);
					out.writeShortBigEndin(v);
					out.skipBytes(0x14);
				}
			} else {
				throw new IOException("UnSupport Nba2K 3D Model Type");
			}
			if (IS_DEBUG)
				System.out.printf("CURuvPOS: %X--%d-%d\n", out.getFilePointer(), vertexNum, perUVNSize);
		}
	}

	private void importIgModelVerts(File modelfile, N2kPackageFile pagFile) throws IOException {
		ByteFileReader in = new ByteFileReader(modelfile, "r");
		ByteFileReader out = new ByteFileReader(file, "rw");
		byte[] buff = new byte[4];
		in.read(buff);
		if (!"2KM".equals(new String(buff).substring(0, 3))) {
			in.close();
			out.close();
			throw new IOException("This is not a Valid N2KM File");
		}
		int num = in.read4BytesAsInt();
		int perSize = in.read4BytesAsInt();
		buff = new byte[8];
		if (IS_DEBUG)
			System.out.println("imp: " + num + ", " + perSize);
		for (int i = 0; i < num; i++) {
			in.read(buff);
			String partName = new String(buff).trim();
			String[] idxStr = partName.split("-");
			int index = Integer.parseInt(idxStr[0]);
			int childIdx = Integer.parseInt(idxStr[1]);
			N2k3DModelPart part = pagFile.models[index];
			//import child vertex data
			importIg3DModelVertexData(in, out, perSize, part);
			int faceNum = in.read4BytesAsInt();
			in.skipBytes(6 * faceNum);
		}
		in.close();
		out.close();
	}

}
